package com.tanhua.server.service;

import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.dubbo.api.db.*;
import com.tanhua.model.db.*;
import com.tanhua.model.vo.*;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 测灵魂业务处理层
 */
@Service
@Slf4j
public class TestSoulService {
    @DubboReference
    private QuestionnairesApi questionnairesApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionsApi questionsApi;

    @DubboReference
    private OptionsApi optionsApi;

    @DubboReference
    private SoulApi soulApi;

    @DubboReference
    private ReportApi reportApi;

    @DubboReference
    private ConclusionApi conclusionApi;

    @DubboReference
    private DimensionApi dimensionApi;

    /**
     * 获取问卷列表，返回对应Vo
     * @return
     */
    public List<QuestionnairesVo> testSoul() {
        Long userId = UserHolder.getUserId();
        //1.调用服务查询questionnaires获取所有问卷对象的集合
        //记得在UserInfo加LevelStatus字段
        List<Questionnaires> questionnairesList = questionnairesApi.getAllQuestionnaires();

        //3.构建Vo,存入问卷Vo集合
        List<QuestionnairesVo> questionnairesVoList = new ArrayList<>();
        for (Questionnaires questionnaires : questionnairesList) {
            //根据问卷id获取对应的问题数组
            //构建questionsVo问题Vo
            List<Questions>  questionsList = questionsApi.findQuestionsByQaId(questionnaires.getId());
            List<QuestionsVo> questionsVoList = new ArrayList<>();
            for (Questions questions : questionsList) {
                QuestionsVo questionsVo = new QuestionsVo();
                questionsVo.setId(questions.getQuestionsId());
                questionsVo.setQuestion(questions.getQuestion());
                //构造OptionsVo存入
                List<Options> options = optionsApi.findOptionsByQuId(questions.getQuestionsId());
                List<OptionsVo> optionsVoList = new ArrayList<>();
                for (Options option : options) {
                    OptionsVo optionsVo = new OptionsVo();
                    optionsVo.setId(option.getOptionsId());
                    optionsVo.setOption(option.getOptiontext());
                    optionsVoList.add(optionsVo);
                }
                questionsVo.setOptions(optionsVoList);
                questionsVoList.add(questionsVo);
            }

            //构建问卷questionnairesVo
            QuestionnairesVo questionnairesVo = new QuestionnairesVo();
            questionnairesVo.setId(questionnaires.getId());
            questionnairesVo.setName(questionnaires.getName());
            questionnairesVo.setCover(questionnaires.getCover());
            questionnairesVo.setLevel(questionnaires.getLevel());
            questionnairesVo.setStar(questionnaires.getStar());

            questionnairesVo.setQuestions(questionsVoList);
            questionnairesVo.setIsLock(JudgeIsLock(userId, questionnaires));
            if(soulApi.findReport(userId,questionnairesVo.getLevel())!=null){
                String reportId = soulApi.findReport(userId,questionnairesVo.getLevel()).getId().toString();
               if(!StringUtils.isEmpty(reportId)){
                   questionnairesVo.setReportId(reportId);
               }
            }
            questionnairesVoList.add(questionnairesVo);
        }



        //4.返回Volist集合
        return questionnairesVoList;

    }

    /**
     * 判断isLock
     * @param userId
     * @param questionnaires
     * @return
     */
    private int JudgeIsLock(Long userId, Questionnaires questionnaires){
        if("1".equals(userInfoApi.getUserInfo(userId).getLevelstatus()) && "初级".equals(questionnaires.getLevel())){
            return 0;
        }
        if("2".equals(userInfoApi.getUserInfo(userId).getLevelstatus())  && ("初级".equals(questionnaires.getLevel()) || "中级".equals(questionnaires.getLevel()))){
            return 0;
        }
        if("3".equals(userInfoApi.getUserInfo(userId).getLevelstatus())){
            return 0;
        }
        return 1;
    }



    /**
     * 提交问卷
     */

    public String submitReport(Map<String,List<AnswerVo>> paramMap) {
        //用户的userId
        Long userId = UserHolder.getUserId();

        Report report = new Report();
        report.setUserId(userId);

        List<AnswerVo> list = paramMap.get("answers");
        report.setOutgoing(0);
        report.setAbstractive(0);
        report.setEstimate(0);
        report.setRational(0);
        for (int i = 0; i <= 9; i++) {
            AnswerVo answerVo = list.get(i);

            //获取每一题的题号
            String questionId = answerVo.getQuestionId();
            //根据题号查询维度号
            String dimensionsId=questionsApi.findDimensions(questionId);


            //获取选项分数
            String optionId = answerVo.getOptionId();
            Integer score = optionsApi.findScore(optionId);

            //判断在哪个维度就添加对应的分数
            if(dimensionsId.equals("1")){
                report.setOutgoing(report.getOutgoing()+score);
            }

            if(dimensionsId.equals("2")){
                report.setEstimate(report.getEstimate()+score);
            }

            if(dimensionsId.equals("3")){
                report.setRational(report.getRational()+score);
            }

            if(dimensionsId.equals("4")){
                report.setAbstractive(report.getAbstractive()+score);
            }
        }

        //查询UserInfo表,判断level是否大于等于3;
        UserInfo userInfo = userInfoApi.getUserInfo(userId);
        Long level = Long.valueOf(userInfo.getLevelstatus());//从userInfo表中过去level

        //根据试题编号,获取问卷编号
        String questionId = list.get(0).getQuestionId();
        String questionairesId = questionsApi.findQuestionairesId(questionId);
        //根据问卷编号,获取用户当前答题的题目等级
        Questionnaires questionaires = questionnairesApi.findLevelByQId(questionairesId);
        String nowLevel = questionaires.getLevel();
        Integer i=0;
        if(nowLevel.equals("初级")){
            i=1;
        }
        if(nowLevel.equals("中级")){
            i=2;
        }
        if(nowLevel.equals("高级")){
            i=3;
        }

        //如果等级大于等于3
        if(level >= 3) {
            log.info("用户所有等级测试题都已解锁!");
            //将userInfo的level设置成最高等级
            userInfo.setLevelstatus("3");

        }
        //设置Report的level参数
        report.setLevel(nowLevel);


        //如果是小于3,判断是否Report存在,如果存在就更新,不存在就插入
        if (level<3&&level==(long)i) {
            log.info("用户所有等级测试题未解锁到最高级!");

//            //设置Report的level参数
//            report.setLevel(nowLevel);

            //将userInfo的level提升一级
            //Long nLevel = Long.valueOf(i+1);
            Integer nLevel=i+1;
            System.out.println("********************************nLevel = *******************" + nLevel);
            userInfo.setLevelstatus(nLevel.toString());
            userInfoApi.update(userInfo);
        }

        //根据用户UserId和nowLevel获取到Report对象

        Report nowReport = soulApi.findReport(userId,nowLevel);
        if (nowReport != null) {
            //更新report表数据
            soulApi.updateReport(report);
        } else {
            //插入report记录
            soulApi.insertReport(report);
        }

        //返回报告id
        nowReport = soulApi.findReport(userId,nowLevel);
        return nowReport.getId().toString();
    }

    /**
     * 查看报告
     * @param reportId
     * @return
     *
     */
    public ReportConclusionVo viewResults(String reportId) {
        // 构建返回的 Vo
        ReportConclusionVo reportConclusionVo = new ReportConclusionVo();

        // 查表获得 维度分
        Report report = reportApi.queryByReportId(reportId);
        Integer outgoing = Integer.valueOf(report.getOutgoing()/2+70) ;
        Integer abstractive = Integer.valueOf(report.getAbstractive()+70);
        Integer estimate = Integer.valueOf(report.getEstimate()+70);
        Integer rational = Integer.valueOf(report.getRational()+70);
        // 获得维度百分数
        String outgoingPercent = outgoing + "%";
        String abstractivePercent = abstractive + "%";
        String estimatePercent = estimate + "%";
        String rationalPercent = rational + "%";
        List<DimensionsVo> dimensionsVos = new ArrayList<>();
        DimensionsVo dimensionsVo1 = new DimensionsVo("外向:", outgoingPercent);
        DimensionsVo dimensionsVo2 = new DimensionsVo("判断:", abstractivePercent);
        DimensionsVo dimensionsVo3 = new DimensionsVo("抽象:", estimatePercent);
        DimensionsVo dimensionsVo4 = new DimensionsVo("理性:", rationalPercent);
        dimensionsVos.add(dimensionsVo1);
        dimensionsVos.add(dimensionsVo2);
        dimensionsVos.add(dimensionsVo3);
        dimensionsVos.add(dimensionsVo4);
        reportConclusionVo.setDimensions(dimensionsVos);

        // 判断最高维度
        String maxType;
        int maxTypeScore = outgoing > abstractive ? outgoing : abstractive;
        maxTypeScore = maxTypeScore > estimate ? maxTypeScore : estimate;
        maxTypeScore = maxTypeScore > rational ? maxTypeScore : rational;
        if (maxTypeScore == outgoing) {
            maxType = "outgoing";
        } else if (maxTypeScore == abstractive) {
            maxType = "abstractive";
        } else if (maxTypeScore == estimate) {
            maxType = "estimate";
        } else {
            maxType = "rational";
        }



        // 用最高维度查 维度 Dimension 表
        // 获得维度描述和维度度图片
        Dimension dimension = dimensionApi.findByType(maxType);
        String description = dimension.getDescription();
        String cover = dimension.getCover();
        Long dimensionId = dimension.getId();
        // 把维度描述和维度度图片放进Vo
        reportConclusionVo.setConclusion(description);
        reportConclusionVo.setCover(cover);

        // 存表
        Conclusion conclusion = new Conclusion();
        conclusion.setUserId(UserHolder.getUserId());

        conclusion.setDimensionId(dimensionId);

        conclusion.setDimensionType(maxType);
        Long reportIdLong = Long.valueOf(reportId);
        conclusion.setReportId(reportIdLong);

        conclusionApi.save(conclusion);


        // 处理相似的人
        // 根据维度类型查报告表。获得 同类型用户的 userIds
        List<Long> userIds = conclusionApi.findByType(maxType, UserHolder.getUserId());
        List<SimilarVo> similarVos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(userIds)){
            similarVos =  userInfoApi.findSimilarByIds(userIds);
        }
        reportConclusionVo.setSimilarYou(similarVos);


        return reportConclusionVo;
    }

}